import { ITypeState } from '@/models/typeModel';
import { IBook } from '@/types/book';
import { typeOptionCreator } from '@/utils/tools';
import { PlusOutlined } from '@ant-design/icons';
import '@toast-ui/editor/dist/i18n/zh-cn';
import '@toast-ui/editor/dist/toastui-editor.css';
import { Editor } from '@toast-ui/react-editor';
import { Button, Form, Image, Input, InputNumber, Select, Upload } from 'antd';
import React, { useEffect, useRef } from 'react';
import { useDispatch, useSelector } from 'umi';

interface IProps {
  type: 'add' | 'edit';
  bookInfo?: IBook;
  handleSubmit: (value: any) => void;
}

const BookForm: React.FC<IProps> = ({
  type,
  bookInfo,
  handleSubmit,
}: IProps) => {
  const [form] = Form.useForm(); // 关联表单
  const editorRef = useRef<any>(); // 关联 markdown 编辑器
  // 从仓库获取所有的分类
  const { typeList }: ITypeState = useSelector((state: any) => state.type);

  const dispatch = useDispatch();

  function handleFinish(value: any) {
    // 因为我们需要获取 markdown editor 的值
    const content = editorRef.current.getInstance().getHTML();
    const bookInfo = { ...value, bookIntro: content };
    if (
      value.bookPic &&
      typeof value.bookPic === 'object' &&
      value.bookPic.file.status === 'done'
    ) {
      bookInfo.bookPic = value.bookPic.file.response.data;
    }
    handleSubmit(bookInfo);
  }

  // 这里需要注意的就是关于有 markdown 编辑器时数据的回填
  useEffect(() => {
    form.resetFields();
    form.setFieldsValue(bookInfo);
    // 对应的组件在重新渲染时，markdown 编辑器回填了数据多次，覆盖了要回填的bookIntro
    // 这里用异步回填来解决
    setTimeout(() => {
      editorRef.current.getInstance().setHTML(bookInfo?.bookIntro);
    }, 100);
  }, [bookInfo]);
  useEffect(() => {
    if (!typeList.length) {
      dispatch({
        type: 'type/_initTypeList',
      });
    }
  }, []);

  let bookPicPreview = null;
  if (type === 'edit') {
    bookPicPreview = (
      <Form.Item label="当前封面" name="bookPicPreview">
        <Image src={bookInfo?.bookPic} width={100} />
      </Form.Item>
    );
  }

  return (
    <Form
      name="basic"
      form={form}
      initialValues={{ ...bookInfo }}
      autoComplete="off"
      onFinish={handleFinish}
    >
      {/* 书籍标题 */}
      <Form.Item
        label="书籍标题"
        name="bookTitle"
        rules={[{ required: true, message: '请输入书名' }]}
        validateTrigger="onBlur"
      >
        <Input />
      </Form.Item>

      {/* 书籍介绍，需要使用到 markdown editor */}
      <Form.Item
        label="书籍介绍"
        name="bookIntro"
        // rules={[{ required: true, message: '请输入书本相关的介绍' }]}
      >
        <Editor
          initialValue=""
          previewStyle="vertical"
          height="500px"
          initialEditType="wysiwyg"
          useCommandShortcut={true}
          language="zh-CN"
          ref={editorRef}
        />
      </Form.Item>

      <Form.Item
        label="下载链接"
        name="downloadLink"
        rules={[{ required: true, message: '请输入书籍链接' }]}
        validateTrigger="onBlur"
      >
        <Input />
      </Form.Item>

      <Form.Item
        label="所需积分"
        name="requirePoints"
        rules={[{ required: true, message: '请输入下载所需积分' }]}
        validateTrigger="onBlur"
      >
        <InputNumber style={{ width: 200 }} min={0} precision={0} />
      </Form.Item>

      <Form.Item
        label="书籍分类"
        name="typeId"
        rules={[{ required: true, message: '请选择书籍分类' }]}
        validateTrigger="onBlur"
      >
        <Select style={{ width: 200 }}>
          {typeOptionCreator(Select, typeList)}
        </Select>
      </Form.Item>

      {/* 书籍图片的预览，这个是在修改书籍的时候会显示之前书籍的图片 */}
      {bookPicPreview}

      <Form.Item label="书籍封面" name="bookPic">
        <Upload action="/api/upload" listType="picture-card" maxCount={1}>
          <PlusOutlined />
        </Upload>
      </Form.Item>

      {/* 确认修改按钮 */}
      <Form.Item wrapperCol={{ offset: 3, span: 16 }}>
        <Button type="primary" htmlType="submit">
          {type === 'add' ? '确认新增' : '修改'}
        </Button>

        <Button type="link" htmlType="reset" className="resetBtn">
          重置
        </Button>
      </Form.Item>
    </Form>
  );
};

export default BookForm;
